package com.algorithm.introduction.lecturetwo;

import com.algorithm.util.FileOperate;

import java.util.ArrayList;
import java.util.List;


/**
 * Created by mi on 2016/11/7.
 */
public class DocumentDistance {
        private static String[] getWordsFromLineArray(String[] lineArray) {
            List<String> words = new ArrayList<>();
            StringBuilder sb = new StringBuilder();
            for (String line : lineArray) {
                char[] charArray = line.toCharArray();
                sb.setLength(0);
                for(char c : charArray){
                    if (Character.isLetterOrDigit(c)) {
                        sb.append(c);
                    } else if (sb.length() != 0) {
                        words.add(sb.toString().toLowerCase());
                        sb.setLength(0);
                    }
                }
                if (sb.length() != 0) {
                    words.add(sb.toString().toLowerCase());
                }
            }
            return words.toArray(new String[words.size()]);
        }

    private static List<List> countFrequency(String[] wordList) {
        List<List> frequencyList = new ArrayList<>();

        for (String word : wordList) {
            boolean inFrequencyList = false;
            for (List frequencyItem : frequencyList) {
                if (frequencyItem.get(0).equals(word)) {
                    inFrequencyList = true;
                    frequencyItem.set(1, (int)frequencyItem.get(1) + 1);
                    break;
                }
            }
            if (!inFrequencyList) {
                List frequency = new ArrayList();
                frequency.add(word);
                frequency.add(1);
                frequencyList.add(frequency);
            }

        }
        return frequencyList;
    }

    private static void insertionSort(List<List> frequencyList) {
        for (int i = 0; i < frequencyList.size(); i++) {
            List frequency = frequencyList.get(i);
            int j = i - 1;
            while (j > -1 && ((String)frequencyList.get(j).get(0)).compareTo((String) frequency.get(0)) > 0) {
                frequencyList.set(j+1, frequencyList.get(j));
                j--;
            }
            frequencyList.set(j+1,frequency);
        }
    }

    private static double dotProduct(List<List> frequencyListOne, List<List> frequencyListTwo) {
        double dotProduct = 0;
        for(List frequencyItemOne : frequencyListOne) {
            for (List frequencyItemTwo : frequencyListTwo) {
                if (frequencyItemOne.get(0).equals(frequencyItemTwo.get(0))) {
                    dotProduct += ((int)frequencyItemOne.get(1) * (int)frequencyItemTwo.get(1));
                }
            }
        }
        return dotProduct;
    }

    private static List<List> getSortedWordFrequencyList(String filename) {
        String[] lines = FileOperate.readFileByLines(filename);
        String[] wordList = getWordsFromLineArray(lines);
        List<List> frequencyList = countFrequency(wordList);
        insertionSort(frequencyList);
        return frequencyList;
    }

    private static double vectorAngle(List<List> frequencyListOne, List<List> frequencyListTwo) {
        double numerator = dotProduct(frequencyListOne,frequencyListTwo);
        double denominator = Math.sqrt(dotProduct(frequencyListOne,frequencyListOne)*dotProduct(frequencyListTwo,frequencyListTwo));
        return Math.acos(numerator/denominator);
    }

    public static void main(String[] args) {
        List<List> frequencyListOne = getSortedWordFrequencyList("C:\\Users\\mi\\Downloads\\MIT-introduction to algorithm\\lec02_code\\docdist1.py");
        List<List> frequencyListTwo = getSortedWordFrequencyList("C:\\Users\\mi\\Downloads\\MIT-introduction to algorithm\\ps2\\README.txt");
        double distance = vectorAngle(frequencyListOne, frequencyListTwo);
        System.out.println(distance);
    }

}
